package main

import (
	"database/sql"
	"fmt"
	"log"
	"math/rand"
	"strconv"

	_ "github.com/lib/pq"
)

const MAX_COUNT = 500

func Print(db *sql.DB) {
	// Print out the balances.
	rows, err := db.Query("SELECT id, balance FROM accounts limit 10")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	fmt.Println("Initial balances:")
	for rows.Next() {
		var id, balance int
		if err := rows.Scan(&id, &balance); err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%d %d\n", id, balance)
	}
}

func readMaxId(db *sql.DB) int {
	rows, err := db.Query("SELECT max(id) id FROM accounts")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	if rows.Next() {
		var id int
		if err := rows.Scan(&id); err != nil {
			log.Printf("%s\n", err)
			return 0
		}
		fmt.Printf("accounts max id is %d\n", id)
		return id
	}
	return 0
}

// ll /tmp/bn-ckdb/*.sst; echo ''; tree /tmp/bn-ckdb/metadata; echo ''; tree /tmp/bn-ckdb/data;
func main() {
	db, err := sql.Open("postgres", "user=root dbname=defaultdb host=localhost port=26257 sslmode=disable")
	if err != nil {
		log.Fatal("error connecting to the database: ", err)
	}
	defer db.Close()

	// Create the "accounts" table.
	if _, err := db.Exec(
		"CREATE TABLE IF NOT EXISTS accounts (id INT PRIMARY KEY, balance INT, c3 STRING, c4 INT, c5 INT, c6 INT, c7 INT, c8 INT)"); err != nil {
		log.Fatal(err)
	}

	maxId := readMaxId(db)

	// Create the "orders" table
	if _, err := db.Exec(
		"CREATE TABLE IF NOT EXISTS orders (" +
			"acc_id INT," +
			"id INT PRIMARY KEY," +
			"total DECIMAL(15, 2)," +
			"CONSTRAINT fk_acc_id FOREIGN KEY (acc_id) REFERENCES accounts" +
			")"); err != nil {
		log.Fatal(err)
	}

	for i := maxId; i < maxId+MAX_COUNT; i++ {
		if i%100 == 0 {
			log.Printf("%d records has been inserted into the table %s\n", i, "accounts")
		}
		r := rand.Intn(MAX_COUNT)
		sql := fmt.Sprintf("INSERT INTO accounts (id, balance, c3, c4, c5, c6, c7, c8) VALUES (%d, %d, '%s', %d, %d, %d, %d, %d)", i+1, r, strconv.Itoa(r+3), r+4, r+5, r+6, r+7, r+8)
		// Insert two rows into the "accounts" table.
		if _, err := db.Exec(sql); err != nil {
			log.Fatal(err)
		}
		for o := 0; o < r; o = o + 100 {
			_sql := fmt.Sprintf("INSERT INTO orders (acc_id, id, total) VALUES(%d, %d, %d)", i+1, i*MAX_COUNT+o, r)
			if _, err := db.Exec(_sql); err != nil {
				log.Fatal(err)
			}
		}
	}

}
